<template>
  <div class="env-bg">
    <el-card class="env-card" :body-style="{ padding: '20px' }">
      <template #header>
        <span class="card-title">环境参数管理</span>
      </template>
      <el-form :model="queryParams" ref="queryFormRef" size="small" :inline="true" v-show="showSearch"
        label-width="100px">
        <el-form-item label="搜索" prop="parameter_name">
          <el-input v-model="queryParams.parameter_name" placeholder="请输入" clearable />
        </el-form-item>
      </el-form>
      <el-row class="metric-row">
        <el-col :span="24" style="text-align: center;">
          <el-radio-group v-model="selectedMetric" size="medium" class="metric-selector">
            <el-radio-button label="temp">温度(摄氏度)</el-radio-button>
            <el-radio-button label="humidity">湿度 (%)</el-radio-button>
            <el-radio-button label="windPower">风力 (m/s)</el-radio-button>
            <el-radio-button label="light">光照 (W/m² )</el-radio-button>
            <el-radio-button label="burden">用电量(kWh)</el-radio-button>
          </el-radio-group>
        </el-col>
      </el-row>
      <el-row :gutter="10" class="action-btn-row">
        <el-col :span="1.5">
          <el-button class="action-btn primary" type="primary" plain size="default" @click="handleAdd">
            <Plus /> 新增
          </el-button>
        </el-col>
        <el-col :span="1.5">
        </el-col>
        <el-col :span="1.5">
          <el-button class="action-btn danger" type="danger" plain size="default" :disabled="multiple"
            @click="handleBatchDelete">
            <Delete /> 删除
          </el-button>
        </el-col>
        <el-col :span="1.5">
          <el-button class="action-btn warning" type="warning" plain size="default" :disabled="multiple"
            @click="handleExport">
            <Download /> 导出
          </el-button>
        </el-col>
        <el-col :span="1.5">
          <el-upload :show-file-list="false" accept=".xlsx,.xls" :before-upload="handleExcelImport">
            <el-button class="action-btn import" type="success" plain size="default">
              <Upload />导入
            </el-button>
          </el-upload>
        </el-col>

        <!-- 新增：用电量预测按钮（仅在选中用电量时显示） -->
        <el-col :span="1.5" v-if="selectedMetric === 'burden'">
          <el-button class="action-btn info" type="info" plain size="default" :disabled="multiple"
            @click="predictByIds">
            <Refresh /> 用电量预测
          </el-button>
        </el-col>




      </el-row>
      <el-table v-loading="loading" :data="fliterInfo" @selection-change="handleSelectionChange"
        :expand-row-keys="expandedRowKeys" @expand-change="handleExpandChange" border row-key="parameter_id">
        <!-- 展开行：显示时段参数值 -->
        <el-table-column type="expand">
          <template #default="props">
            <div class="expand-container">
              <!-- 加载状态 -->
              <el-loading v-if="expandedLoading[props.row.parameter_id]" text="加载数据中..." fullscreen="false" />

              <template v-else>

                <!-- 左右分栏容器 -->
                <div class="split-layout">
                  <!-- 左侧：ECharts 图表（40%宽度） -->
                  <!-- 左侧：引入图表组件 -->
                  <PriceChart class="chart-container" :data="props.row.values || []"
                    :title="`${props.row.category_id || '0'}`" />

                  <!-- 右侧：子表格（60%宽度） -->
                  <div class="table-container">
                    <el-table :data="props.row.values || []" border height="300px" size="small" style="width: 100%;">
                      <el-table-column label="序号" type="index" width="60" align="center" />
                      <el-table-column label="时间点" prop="time_point" align="center">
                        <template #default="scope">
                          {{ formatTime(scope.row.time_point) }}
                        </template>
                      </el-table-column>
                      <el-table-column label="具体数值" prop="price_amount" align="center" />
                      <!-- <el-table-column label="操作" width="150" align="center">
                        <template #default="scope">
                          <el-button type="danger" size="small" @click="deleteTimePrice(props.row, scope.$index)">
                            <Delete /> 删除
                          </el-button>
                        </template>
                      </el-table-column> -->
                    </el-table>
                  </div>
                </div>
              </template>
            </div>
          </template>
        </el-table-column>
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="ID" align="center" prop="parameter_id" />
        <el-table-column label="划分周期单位" align="center" prop="period_unit" />
        <el-table-column label="划分周期" align="center" prop="period" />
        <el-table-column label="分类名称" align="center" prop="parameter_name" />
        <el-table-column label="划分粒度" align="center" prop="granularity" />
        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-button size="small" type="danger" @click="handleDelete(scope.row)" class="icon-btn">
              <Delete /> 删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!--    <pagination-->
      <!--        v-show="total > 0"-->
      <!--        :total="total"-->
      <!--        :page.sync="queryParams.pageNum"-->
      <!--        :limit.sync="queryParams.pageSize"-->
      <!--        @pagination="getList"-->
      <!--    />-->

      <!-- 添加或修改对话框 -->
      <el-dialog :title="title" v-model="open" width="700px" max-height="600px" append-to-body>
        <!-- 修改 el-dialog 内部表单及控件标签 -->
        <!-- el-form -->
        <el-form ref="formRef" :model="form" :rules="rules" label-width="150px" class="env-parameter-form">
          <!-- 划分周期单位：下拉框选择 day/week/hour -->
          <el-form-item label="划分周期单位" prop="period_unit">
            <el-select v-model="form.period_unit" placeholder="请选择划分周期单位" @change="handleperiod_unitChange" disabled
              class="env-form-select">
              <el-option label="天" value="day" />
            </el-select>
          </el-form-item>
          <!-- 划分周期：手动输入 -->
          <el-form-item label="划分周期" prop="period">
            <el-input v-model="form.period" placeholder="请输入划分周期（如：1表示1个单位周期）" disabled class="env-form-input" />
          </el-form-item>
          <!-- 划分粒度：根据周期单位动态变化选项 -->
          <el-form-item label="划分粒度" prop="granularity">
            <el-select v-model="form.granularity" placeholder="请选择划分粒度" @change="handleGranularityChange" disabled
              class="env-form-select">
              <el-option v-for="item in granularityOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
          <!-- 参数名称：下拉框（显示名称+对应value值） -->
          <el-form-item label="参数类型" prop="parameter_name">
            <el-select v-model="form.parameter_name" placeholder="请选择参数类型" @change="handleprice_typeChange"
              class="env-form-select">
              <el-option label="温度" value="1" />
              <el-option label="湿度" value="2" />
              <el-option label="风力" value="3" />
              <el-option label="光照" value="4" />
              <el-option label="用电量" value="5" />
            </el-select>
          </el-form-item>
          <!-- 新增：参数时间点表格（根据粒度动态生成） -->
          <el-form-item label="时段参数值" prop="values" class="values-table">
            <div class="table-container_dialog">
              <div class="add-button-container">
                <el-button type="info" :icon="Plus" circle @click="addRow" class="add-btn" />
              </div>
              <el-table :data="form.values" height="300px" border style="width: 100%">
                <el-table-column label="序号" type="index" width="60" align="center" />
                <el-table-column label="时间点" prop="time_point" width="200px" align="center">
                  <template #default="scope">
                    <el-date-picker v-model="scope.row.time_point" type="datetime" format="YYYY-MM-DD HH:mm:ss"
                      value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择时间点" size="default" style="width: 100%;"
                      @change="handleTimeChange(scope.$index)" />
                  </template>
                </el-table-column>
                <el-table-column label="具体数值" align="center">
                  <template #default="scope">
                    <el-input v-model.number="scope.row.price_amount" placeholder="请输入参数" type="number" min="0"
                      step="0.01" @change="handlePriceChange(scope.$index)" class="env-form-input" />
                  </template>
                </el-table-column>
                <el-table-column label="操作" width="100" align="center">
                  <template #default="scope">
                    <el-button type="danger" size="small" @click="removeRow(scope.$index)">
                      删除
                    </el-button>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button @click="cancel" class="cancel-btn">取 消</el-button>
          <el-button type="primary" @click="submitForm" class="confirm-btn">确 定</el-button>
        </div>
      </el-dialog>
    </el-card>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, watch, computed } from 'vue';
import { useRouter } from 'vue-router';
import { ElMessage, ElMessageBox } from 'element-plus';
import { getParameterByCategoryId, getTimeZoneInfo, exportEnvByIds, addParameter, batchDeleteByIds } from "../api/system/parameter.js"
// 导入 API 服务
import { getInfo, delInfo, updateInfo, predictElectricPrice } from "../api/system/elecPrice.js";
import { downloadFile } from "../utils/download.js";
// 导入图标组件
import { Edit, Delete, Plus, Search, Refresh, Download, Upload } from '@element-plus/icons-vue';
import PriceChart from "../components/PriceChart.vue";
import * as XLSX from 'xlsx';

const selectedMetric = ref('temp')
// 表单引用
const queryFormRef = ref(null);
const formRef = ref(null);

// 状态管理
const loading = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const showSearch = ref(true);
const total = ref(0);
const infoList = ref([]);
const title = ref('');
const open = ref(false);
// 粒度选项（根据周期单位动态生成）
const granularityOptions = ref([]);
// 查询参数
const queryParams = reactive({
  pageNum: 1,
  pageSize: 10,
  period_unit: null,
  period: null,
  price_type: null,
  granularity: null,
  parameter_name: null
});
const category_id_mapping = {
  "temp": 1,
  "humidity": 2,
  "windPower": 3,
  "light": 4,
  "burden": 5
}
// 表单数据
const form = reactive({
  priceId: null,
  period_unit: 'day',
  period: 1,
  price_type: null,
  granularity: 24,
  parameter_name: null,
  values: []    // 时段参数值数组：[{time_point, price_amount}, ...]
});

watch(selectedMetric, () => {
  expandedRowKeys.value = []
})

// 表单校验规则
const rules = reactive({
  period_unit: [
    { required: true, message: "划分周期单位不能为空", trigger: "blur" }
  ],
  period: [
    { required: true, message: "划分周期不能为空", trigger: "blur" }
  ],
  price_type: [
    { required: true, message: "参数类型不能为空", trigger: "change" }
  ],
  granularity: [
    { required: true, message: "划分粒度不能为空", trigger: "blur" }
  ],
  parameter_name: [
    { required: true, message: "参数名称不能为空", trigger: "blur" }
  ]
});
// 在<script setup>中添加或修正此方法
const formatTime = (isoTime) => {
  if (!isoTime) return ''; // 处理空值
  const date = new Date(isoTime);
  // 格式化时间为 "YYYY-MM-DD HH:mm:ss"
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: false
  }).replace(/\//g, '-'); // 将斜杠替换为横杠（如 2025/07/11 → 2025-07-11）
};
// 存储展开行的加载状态（避免重复请求）
const expandedLoading = reactive({});
// 展开/折叠行时触发
// 展开/折叠行时触发（核心修改）
const expandedRowKeys = ref([]);
const handleExpandChange = async (row, expandedRows) => {
  const priceId = row.parameter_id;
  // 如果已经展开，说明是收起操作，直接移除
  if (expandedRowKeys.value.includes(priceId)) {
    expandedRowKeys.value = expandedRowKeys.value.filter(id => id !== priceId);
    return;
  }
  // 否则是展开操作，先 loading
  expandedLoading[priceId] = true;
  try {
    const res = await getTimeZoneInfo(priceId);
    const { time_list, value_list } = res.data.data;
    row.values = time_list.map((time, index) => ({
      time_point: time,
      price_amount: value_list[index] || 0
    }));
    // 数据加载完再展开
    expandedRowKeys.value.push(priceId);
  } catch (e) {
    ElMessage.error('加载失败');
  } finally {
    expandedLoading[priceId] = false;
  }
};
// 粒度选择变化时，生成时间点
const handleGranularityChange = () => {
  generateTimePoints();
};
// 周期单位变化时，更新粒度选项
const handleperiod_unitChange = (value) => {
  // 清空当前粒度选择（避免选项不匹配）
  form.granularity = null;
  form.values = [];

  // 根据周期单位生成对应粒度选项
  switch (value) {
    case 'day':
      // 天：1-24小时
      granularityOptions.value = Array.from({ length: 24 }, (_, i) => ({
        label: `${i + 1}小时`,
        value: i + 1
      }));
      break;
    case 'week':
      // 周：按天划分（1-7天）或按小时划分（1-168小时，每周7*24=168小时）
      // 这里选择按天划分，更符合周级调度习惯
      granularityOptions.value = Array.from({ length: 7 }, (_, i) => ({
        label: `${i + 1}天`,
        value: i + 1
      }));
      break;
    case 'hour':
      // 小时：按15分钟粒度划分（1-4个区间，每15分钟为1单位）
      granularityOptions.value = [
        { label: '15分钟', value: 1 },
        { label: '30分钟', value: 2 },
        { label: '45分钟', value: 3 },
        { label: '60分钟', value: 4 }
      ];
      break;
    default:
      granularityOptions.value = [];
  }
  // 新增：如果已有粒度值，立即生成时间点
  // 新增：如果已有粒度值，立即生成时间点
  if (form.granularity) {
    generateTimePoints();
  }
};


const fliterInfo = computed(() => {
  if (!queryParams.parameter_name || !queryParams.parameter_name.trim()) {
    return infoList.value; // 无搜索词时返回全部数据
  }

  const query = queryParams.parameter_name.trim().toLowerCase();
  return infoList.value.filter(parameter => {
    // 在名称或型号中进行模糊匹配
    return parameter.parameter_name.toLowerCase().includes(query)

  });
});
// 根据粒度生成时间点（核心逻辑）
const generateTimePoints = () => {
  form.values = []; // 清空现有数据

  const { period_unit, granularity } = form;
  if (!period_unit || !granularity) return;

  // 生成当前日期（可根据需求改为周期起始日期）
  const baseDate = new Date();
  const year = baseDate.getFullYear();
  const month = String(baseDate.getMonth() + 1).padStart(2, '0');
  const day = String(baseDate.getDate()).padStart(2, '0');
  const baseDateStr = `${year}-${month}-${day}`;

  // 1. 周期单位为"天"（day）：生成0-23点
  if (period_unit === 'day' && granularity === 24) {
    for (let i = 0; i < 24; i++) {
      const hour = String(i).padStart(2, '0');
      form.values.push({
        time_point: `${baseDateStr} ${hour}:00:00`, // 格式：2025-07-11 00:00:00
        price_amount: null // 初始为空，等待用户输入
      });
    }
  }

  // // 2. 周期单位为"周"（week）：生成周一到周日
  // if (period_unit === 'week' && granularity === 7) {
  //   for (let i = 0; i < 7; i++) {
  //     const tempDate = new Date(baseDate);
  //     tempDate.setDate(baseDate.getDate() + i); // 往后推i天
  //     const weekDay = tempDate.toLocaleDateString('zh-CN', { weekday: 'long' }); // 星期几
  //     const dateStr = `${tempDate.getFullYear()}-${String(tempDate.getMonth() + 1).padStart(2, '0')}-${String(tempDate.getDate()).padStart(2, '0')}`;
  //     form.values.push({
  //       time_point: `${dateStr}（${weekDay}）`, // 格式：2025-07-11（星期五）
  //       price_amount: null
  //     });
  //   }
  // }

  // 3. 周期单位为"小时"（hour）：生成4个15分钟
  // if (period_unit === 'hour' && granularity === 4) {
  //   const hour = String(baseDate.getHours()).padStart(2, '0');
  //   const minutes = ['00', '15', '30', '45'];
  //   minutes.forEach(min => {
  //     form.values.push({
  //       time_point: `${baseDateStr} ${hour}:${min}:00`, // 格式：2025-07-11 14:00:00
  //       price_amount: null
  //     });
  //   });
  // }
};


// 处理时间修改
const handleTimeChange = (index) => {
  // 获取当前行数据
  const row = form.values[index];
  if (row.time_point) {
    // 转换为ISO格式
    const date = new Date(row.time_point);
    row.time_point = date.toISOString();
    console.log(`第${index + 1}行时间已更新为:`, row.time_point);
  }
};

// 处理参数值修改
const handlePriceChange = (index) => {
  const row = form.values[index];
  console.log(`第${index + 1}行参数已更新为:`, row.price_amount);
};

// 辅助函数：将 YYYY-MM-DD HH:mm:ss 转换为 ISO 格式
const formatToISODate = (dateStr) => {
  if (!dateStr) return null;

  // 处理带空格的日期时间格式
  const isoDate = dateStr.replace(' ', 'T') + 'Z';
  return new Date(isoDate).toISOString();
};
// 添加新行
const addRow = () => {
  // 获取当前时间作为默认值
  const now = new Date();
  const formattedTime = now.toISOString().slice(0, 19).replace('T', ' ');

  // 添加新行到表格末尾
  form.values.push({
    time_point: formattedTime,
    price_amount: 0
  });
  console.log("时段参数值数据", form.values)
};

//处理名称和类型的联动
const handleprice_typeChange = (selectedValue) => {
  // 1. 将value赋值给price_type
  form.price_type = selectedValue;

  // 2. 根据value查找对应的label
  const selectedOption = [
    { label: "温度", value: "1" },
    { label: "湿度", value: "2" },
    { label: "风力", value: "3" },
    { label: "光照", value: "4" },
    { label: "用电量", value: "5" }

  ].find(item => item.value === selectedValue);

  // 3. 将label赋值给parameter_name
  if (selectedOption) {
    form.parameter_name = selectedOption.label;
  }
};

function handleExcelImport(file) {
  const reader = new FileReader()
  let requestBody = {}
  reader.onload = (e) => {
    const data = e.target.result
    const workbook = XLSX.read(data, { type: 'binary' })
    const firstSheetName = workbook.SheetNames[0]
    const worksheet = workbook.Sheets[firstSheetName]
    const jsonData = XLSX.utils.sheet_to_json(worksheet)
    // jsonData 就是Excel里的数据数组
    let values = []
    jsonData.forEach(item => {
      values.push({
        'time_point': item['时间点'],
        'value': item['值'],
      })
    })
    requestBody = {
      'period_unit': 'day',
      'period': 1,
      'granularity': 24,
      'icon': '',
      'background': '',
      'category_id': jsonData[0]['参数类别ID'],
      'parameter_name': jsonData[0]['参数名'],
      'values': values
    }
    console.log(requestBody)
    if (requestBody.parameter_name == null || requestBody.values == null || requestBody.category_id == null) {
      ElMessage.error('请检查文件格式')
      return
    }
    addParameter(requestBody).then(res => {
      ElMessage.success('导入成功')
      getList()
    }).catch(error => {
      ElMessage.error('导入失败')
    })
  }
  reader.readAsBinaryString(file)
}
// 删除行
const removeRow = (index) => {
  form.values.splice(index, 1);
};
// 生命周期钩子
onMounted(() => {
  getList();
});

// 获取数据列表
const getList = async () => {
  open.value = false;
  loading.value = true;
  try {
    const res = await getParameterByCategoryId(category_id_mapping[selectedMetric.value]);
    infoList.value = res.data.data || [];
    total.value = res.data.total || 0;
  } catch (error) {
    ElMessage.error('获取数据失败');
  } finally {
    loading.value = false;
  }
};

// 重置表单
const reset = () => {

  form.period_unit = 'day';
  form.period = 1;
  form.price_type = null;
  form.granularity = 24;
  form.parameter_name = null;

  formRef.value?.resetFields();
};


// 多选框选中变化
const handleSelectionChange = (selection) => {
  ids.value = selection.map(item => item.parameter_id);
  console.log(ids.value)
  single.value = selection.length !== 1;
  multiple.value = !selection.length;
};

// 新增操作
const handleAdd = () => {
  console.log("新增操作")
  reset();
  title.value = "添加参数信息";
  open.value = true;
};



// 提交表单
const submitForm = () => {
  const requiredCount = 24;
  if (!form.values || form.values.length < requiredCount) {
    const left = requiredCount - (form.values ? form.values.length : 0);
    ElMessage.warning(`还需输入${left}条数据`);
    return;
  }
  formRef.value.validate(valid => {
    if (!valid) {
      ElMessage.error('请填写必填字段');
      return;
    }
    // 构建符合后端要求的数据对象
    const payload = {
      category_id: category_id_mapping[selectedMetric.value],
      period_unit: form.period_unit,
      period: Number(form.period), // 转换为数值
      granularity: form.granularity,
      parameter_name: form.parameter_name, // 修正字段名
      icon: '',
      background: '',
      values: form.values.map(item => ({
        ...item,
        time_point: formatToISODate(item.time_point), // 转换时间格式
        value: Number(item.price_amount) // 确保为数值
      }))
    };
    console.log('提交的数据:', JSON.stringify(form, null, 2));
    // const action = form.priceId ? updateInfo(payload) : addParameter(payload);

    addParameter(payload).then(() => {
      ElMessage.success('新增成功');
      open.value = false;
      getList();
    }).catch(error => {
      ElMessage.error('操作失败: ' + (error.message || '未知错误'));
    });
  });
};

// 删除操作
const handleDelete = async (row) => {
  const parameter_id = row.parameter_id;
  const data = {
    "parameter_ids": [parameter_id]
  }
  batchDeleteByIds(data).then(() => {
    ElMessage.success('删除成功');
    getList();
  }).catch(error => { // 处理异常
    ElMessage.error('删除失败: ' + (error.message || '未知错误'));
  });
};

// 批量删除操作
const handleBatchDelete = async () => {
  console.log(ids.value)
  const data = {
    "parameter_ids": ids.value
  }
  batchDeleteByIds(data).then(() => {
    ElMessage.success('删除成功');
    getList();
  }).catch(error => {
    ElMessage.error('删除失败');
  })

};

// 导出操作 
const handleExport = () => {
  const data = {
    "param_ids": ids.value
  }
  exportEnvByIds(data).then(res => {
    downloadFile(res.data, '参数详情.xlsx')
    ElMessage.success('导出成功');
  }).catch(error => {
    ElMessage.error('导出失败 ');
  })
};

const predictByIds = () => {
  // 1. 验证是否只勾选了一条数据
  if (ids.value.length !== 1) {
    ElMessage.warning('请勾选一条数据进行预测');
    return;
  }

  // 2. 获取选中数据的 parameter_id
  const selectedParameterId = ids.value[0];
  console.log(infoList.value)

  // 3. 从数据源中查找完整数据对象
  const selectedRecord = infoList.value.find(item => item.parameter_id === selectedParameterId);

  // 4. 校验是否找到数据（未找到则提示）
  if (!selectedRecord) {
    ElMessage.error('找不到选中的数据，请刷新后重试');
    return;
  }

  // 5. 映射参数类型到接口需要的类型（用电量对应 'load'）
  // 环境参数中用电量的 parameter_name 对应的值是 '用电量'，price_type 为 5（根据你的下拉框配置）
  const typeMap = { 5: 'load' }; // 5 对应用电量类型
  const type = typeMap[selectedRecord.category_id];

  if (type === undefined) {
    ElMessage.error('未知的参数类型，请检查数据');
    return;
  }

  // 6. 调用预测接口
  predictElectricPrice(type, selectedParameterId)
    .then((res) => {
      ElMessage.success('预测成功');
      getList();
      // 可根据接口返回结果处理，例如展示预测数据
      console.log('预测结果:', res.data);
    })
    .catch((error) => {
      ElMessage.error('预测失败: ' + (error.message || '未知错误'));
    });
};

// 取消操作
const cancel = () => {
  open.value = false;
  reset();
};
// 监听
watch(selectedMetric, async (newValue) => {
  // 发送请求前设置加载状态
  loading.value = true
  console.log(newValue)
  try {
    // 发送请求到后端API
    const response = await getParameterByCategoryId(category_id_mapping[newValue])
    infoList.value = response.data.data
  } catch (error) {
    console.error('获取数据失败:', error)
    // 可以在这里添加错误处理逻辑
  } finally {
    // 请求完成后重置加载状态
    loading.value = false
  }
}, {
  immediate: true // 立即执行一次，确保初始值也会触发请求
})



</script>

<style scoped>
.env-bg {
  min-height: 100vh;
  background-color: #f9fbfd;
  color: #222;
  font-family: Arial, sans-serif;
  padding: 20px 0;
}

.env-card {
  background: #ffffff;
  border-radius: 10px;
  border: 1px solid #d1d7dc;
  margin: 20px auto;
  box-shadow: 0 2px 8px rgba(90, 150, 255, 0.08);
  max-width: 1400px;
}

.card-title {
  font-size: 20px;
  font-weight: bold;
  color: #1976d2;
}

/* 覆盖图标容器的行高 */
:deep(.el-input__icon) {
  line-height: 1 !important;
}

/* 确保图标正确显示的关键样式 */
.icon-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  /* 图标与文字间距 */
}

/* 强制设置图标尺寸（解决0*0问题） */
:deep(.el-icon) {
  width: 14px !important;
  height: 14px !important;
  display: inline-block !important;
}

/* 修复可能的样式冲突 */
:deep(svg) {
  width: 14px !important;
  height: 14px !important;
  vertical-align: middle;
  text-align: center;
}

.add-button-container {
  text-align: right;
  margin-bottom: 10px;
}

.table-container_dialog {
  width: 100%;
}

.expand-container {
  padding: 15px;
}

/* 左右分栏布局 */
.split-layout {
  display: flex;
  gap: 20px;
  /* 两栏间距 */
  width: 100%;
}

/* 左侧图表容器（40%宽度） */
.chart-container {
  width: 50%;
  height: 300px;
  /* 固定高度，确保图表显示 */
  min-width: 300px;
  /* 最小宽度，避免过窄 */
  border: 1px solid #ebeef5;
  border-radius: 4px;
}

/* 右侧表格容器（60%宽度） */
.table-container {
  width: 50%;
  min-width: 400px;
  /* 最小宽度，避免表格变形 */
}

/* 子表格列宽优化 */
:deep(.el-table .el-table__cell) {
  padding: 8px 0;
}

/* 按钮统一样式 */
:deep(.action-btn-row) {
  margin-bottom: 18px;
  display: flex;
  align-items: center;
  gap: 12px;
}

:deep(.action-btn) {
  border-radius: 20px !important;
  font-size: 15px !important;
  font-weight: 500;
  min-width: 90px;
  height: 38px;
  box-shadow: 0 2px 8px rgba(90, 150, 255, 0.08);
  transition: all 0.2s;
  margin-right: 8px;
  letter-spacing: 1px;
}

:deep(.action-btn.primary) {
  background: #64b5f6 !important;
  color: #1976d2 !important;
  border: none;
}

:deep(.action-btn.primary:hover) {
  color: #fff !important;
  background: #42a5f5 !important;
}

:deep(.action-btn.danger) {
  background: #ef9a9a !important;
  color: #b71c1c !important;
  border: none;
}

:deep(.action-btn.danger:hover) {
  color: #fff !important;
  background: #e57373 !important;
}

:deep(.action-btn.warning) {
  background: #ffe082 !important;
  color: #bfa100 !important;
  border: none;
}

:deep(.action-btn.warning:hover) {
  color: #fff !important;
  background: #ffd54f !important;
}

:deep(.action-btn.success) {
  background: #a5d6a7 !important;
  color: #388e3c !important;
  border: none;
}

:deep(.action-btn.success:hover) {
  color: #fff !important;
  background: #66bb6a !important;
}

:deep(.action-btn.import) {
  background: #e1bee7 !important;
  /* 淡紫色 */
  color: #6a1b9a !important;
  border: none;
}

:deep(.action-btn.import:hover) {
  color: #fff !important;
  background: #ab47bc !important;
}

/* 覆盖原有按钮行样式 */
.mb8.action-btn-row {
  margin-bottom: 18px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.metric-row {
  margin-bottom: 18px;
}

:deep(.metric-selector) {
  background: #f8fafc;
  border-radius: 16px;
  box-shadow: 0 2px 8px rgba(90, 150, 255, 0.08);
  padding: 8px 24px;
  display: inline-block;
}

:deep(.el-radio-button__inner) {
  border-radius: 12px !important;
  background: #f5f7fa;
  color: #000000;
  font-size: 15px;
  font-weight: 500;
  border: none;
  margin: 0 6px;
  min-width: 110px;
  transition: background 0.2s, color 0.2s;
  box-shadow: none;
}

:deep(.el-radio-button__orig-radio:checked + .el-radio-button__inner) {
  background: linear-gradient(90deg, #1976d2 0%, #42a5f5 100%);
  color: #fff;
  font-weight: bold;
  box-shadow: 0 2px 8px rgba(90, 150, 255, 0.12);
}

:deep(.el-radio-button__inner:hover) {
  background: #e3f2fd;
  color: #1976d2;
}

/* 在 style 里添加 info 按钮圆角样式，颜色保持 info 类型 */
:deep(.action-btn.info) {
  background: #b3e5fc !important;
  color: #0277bd !important;
  border: none;
}

:deep(.action-btn.info:hover) {
  color: #fff !important;
  background: #4fc3f7 !important;
}

.action-btn:disabled,
.action-btn[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
  background: #e0e0e0 !important;
  color: #aaa !important;
  border: none !important;
}

/* EnvParameter 对话框样式，参考 ElecPrice.vue */
:deep(.el-dialog) {
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
  overflow: hidden;
}

:deep(.el-dialog__header) {
  background: linear-gradient(135deg, #1976d2 0%, #42a5f5 100%);
  padding: 24px 30px 20px;
  margin: 0;
  border-bottom: none;
}

:deep(.el-dialog__title) {
  color: #ffffff;
  font-size: 20px;
  font-weight: 700;
  text-align: center;
  letter-spacing: 0.5px;
  width: 100%;
  display: block;
}

:deep(.el-dialog__headerbtn) {
  top: 24px;
  right: 30px;
}

:deep(.el-dialog__headerbtn .el-dialog__close) {
  color: #ffffff;
  font-size: 20px;
  font-weight: bold;
}

:deep(.el-dialog__headerbtn:hover .el-dialog__close) {
  color: #e3f2fd;
  transform: scale(1.1);
}

:deep(.el-dialog__body) {
  padding: 30px;
  background: #fafbfc;
}

.env-parameter-form {
  background: #ffffff;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}

:deep(.env-parameter-form .el-form-item) {
  margin-bottom: 24px;
}

:deep(.env-parameter-form .el-form-item__label) {
  color: #374151;
  font-weight: 500;
  font-size: 14px;
  line-height: 1.5;
}

:deep(.env-parameter-form .el-form-item__content) {
  line-height: 1;
}

.env-form-input,
.env-form-select {
  border-radius: 8px;
  transition: all 0.3s ease;
  width: 100%;
}

:deep(.env-form-input .el-input__wrapper),
:deep(.env-form-select .el-select__wrapper) {
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  border: 1px solid #e5e7eb;
  transition: all 0.3s ease;
  background: #ffffff;
}

:deep(.env-form-input .el-input__wrapper:hover),
:deep(.env-form-select .el-select__wrapper:hover) {
  border-color: #90caf9;
  box-shadow: 0 4px 8px rgba(25, 118, 210, 0.1);
}

:deep(.env-form-input .el-input__wrapper.is-focus),
:deep(.env-form-select .el-select__wrapper.is-focus) {
  border-color: #1976d2;
  box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);
}

:deep(.env-form-input .el-input__inner),
:deep(.env-form-select .el-select__selected-item) {
  color: #374151;
  font-size: 14px;
  padding: 5px 10px;
}

:deep(.env-form-input .el-select__selected-item.is-transparent) {
  color: #9ca3af;
  font-size: 14px;
}

:deep(.env-form-input .el-input__inner::placeholder),
:deep(.env-form-select .el-select__selected-item.is-transparent) {
  color: #9ca3af;
  font-size: 14px;
  opacity: 1;
}

:deep(.env-form-select .el-select__wrapper.is-disabled) {
  background: #f5f7fa !important;
  border: 1px solid #e5e7eb !important;
}

:deep(.env-form-select .el-select__selected-item.is-placeholder) {
  color: #9ca3af !important;
  font-size: 14px !important;
  opacity: 1 !important;
}

:deep(.el-dialog__footer) {
  background: #ffffff;
  padding: 20px 30px 30px;
  border-top: 1px solid #f3f4f6;
  margin: 0;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.cancel-btn {
  border-radius: 8px;
  padding: 10px 24px;
  margin-top: 10px;
  font-weight: 500;
  border: 1px solid #d1d5db;
  color: #6b7280;
  background: #ffffff;
  transition: all 0.3s ease;
}

.cancel-btn:hover {
  border-color: #9ca3af;
  color: #374151;
  background: #f9fafb;
  transform: translateY(-1px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.confirm-btn {
  border-radius: 8px;
  padding: 10px 24px;
  font-weight: 500;
  margin-top: 10px;
  background: linear-gradient(135deg, #1976d2 0%, #42a5f5 100%);
  border: none;
  color: #ffffff;
  transition: all 0.3s ease;
}

.confirm-btn:hover {
  background: linear-gradient(135deg, #1565c0 0%, #1976d2 100%);
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(25, 118, 210, 0.3);
}

.confirm-btn:active {
  transform: translateY(0);
  box-shadow: 0 2px 8px rgba(25, 118, 210, 0.2);
}

.add-btn {
  background: linear-gradient(135deg, #1976d2 0%, #42a5f5 100%);
  border: none;
  box-shadow: 0 2px 8px rgba(25, 118, 210, 0.2);
  transition: all 0.3s ease;
}

.add-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(25, 118, 210, 0.3);
}
</style>